﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;
using httpExplorer.Message;

namespace httpExplorer.ViewModel
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class OutputViewModel : ViewModelBase
    {

        private string _welcome = "...";
        public string Welcome
        {
            get
            {
                return _welcome;
            }
            set
            {
                _welcome = value;
                RaisePropertyChanged("Welcome");
            }
        }

        private WebReponse _selectedWebReponse;
        public WebReponse SelectedWebReponse
        {
            get
            {
                return _selectedWebReponse;
            }
            set
            {
                _selectedWebReponse = value;
                RaisePropertyChanged("SelectedWebReponse");
            }
        }

        private ObservableCollection<WebReponse> _responsesCollection = new ObservableCollection<WebReponse>();

        public ObservableCollection<WebReponse> ResponsesCollection
        {
            get { return _responsesCollection; }
            private set { 
                _responsesCollection = value;
                RaisePropertyChanged("ResponsesCollection");
            }
        }

        /// <summary>
        /// Initializes a new instance of the OutputViewModel class.
        /// </summary>
        public OutputViewModel()
        {
            if (IsInDesignMode)
            {
                // Code runs in Blend --> create design time data.
            }
            else
            {
                // Code runs "for real": Connect to service, etc...
                Messenger.Default.Register<ResponseMessage>(this, DisplayOutput);
            }
        }

        private void DisplayOutput(ResponseMessage message)
        {
            HttpWebResponse response = message.Response;
            if (response == null)
            {
                ResponsesCollection.Insert(0, new WebReponse
                {
                    Time = DateTime.Now,
                    Description ="No Connection",
                    ResponseBody = "Unable to connect to server"
                });
                return;
            }


            // Populate the web request
            HttpWebRequest request = message.Request;
            var requestHeaders = new List<KeyValue>();
            if (request != null)
            {
                for (int i = 0; i < request.Headers.Count; i++)
                {
                    requestHeaders.Add(new KeyValue { Key = request.Headers.Keys[i], Value = request.Headers[i] });
                }
            }

            // Populate the web response 
            string responseBody = string.Empty;
            var responseStream = response.GetResponseStream();
            if (responseStream != null)
            {
                var responseReader = new StreamReader(responseStream);
                responseBody = responseReader.ReadToEnd();
            }

            var responseHeaders = new List<KeyValue>();
            for (int i = 0; i < response.Headers.Count; i++)
            {
                responseHeaders.Add( new KeyValue { Key=response.Headers.Keys[i], Value = response.Headers[i]});
            }

            ResponsesCollection.Insert(0, new WebReponse
                               {
                                   Time = DateTime.Now,
                                   Code = (int) response.StatusCode,
                                   Description =  response.StatusCode.ToString(),
                                   Url = response.ResponseUri.ToString(),
                                   RequestHeaders = requestHeaders,
                                   ResponseBody = responseBody,
                                   ResponseHeaders = responseHeaders
                               } );

        }

        ////public override void Cleanup()
        ////{
        ////    // Clean own resources if needed

        ////    base.Cleanup();
        ////}
    }

    public class WebReponse
    {
        public DateTime Time { get; set; }
        public int Code { get; set; }
        public string Description { get; set; }
        public string Url { get; set; }
        public string RequestBody { get; set; }
        public string ResponseBody { get; set; }
        public List<KeyValue> RequestHeaders  { get; set; }
        public List<KeyValue> ResponseHeaders  { get; set; }
    }

    public class KeyValue
    {
        public string Key { get; set; }
        public string Value { get; set; }
    }
}